import requests
import json
from datetime import datetime
from distutils.util import strtobool
from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger
from common.notice_tools import NoticeTools
from app.monitor_metrics.models.prom_alarm_record import PromAlarmRecord
from app.fault_self_recovery.models.fsr_host_disk import FSRHostDisk
from setting import config

class CallbackHostDiskHandler():
    """  Self Healing Handler
    """
    def __init__(self):
        self.handle_url = config.FSR_HOST_DISK_URL
        self.notice_tools = NoticeTools()


    def post_host_disk_usage(self, db: Session, data: dict):
        """
        服务器磁盘使用率过高
        """
        try:
            logger.info(f"host disk usage 收到回调告警信息=>{data}")

            # 前期数据判断
            if data["labels"]["token"] != "2X2n3PrIE81md3nc":
                # token验证
                logger.error(f"{data['fingerprint']} => host disk usage abnormal: token is error")
                return False

            # 检查数据库中的配置信息
            ip = data['labels']['instance'].replace(":9100", "")
            mountpoint = data['labels']['mountpoint']
            host_disk_object = FSRHostDisk.get_object_by_ip_mountpoint(db, ip, mountpoint)
            # 挂载点匹配查询
            if not host_disk_object:
                # 是否配置所有挂载点，脚本那边不区分挂载点全部磁盘清理。
                host_disk_object = FSRHostDisk.get_object_by_ip_allpoint(db, ip)
                if not host_disk_object:
                    # 没有配置自动清理脚本，不处理
                    logger.warning(f"ip:{ip} mountpoint:{mountpoint} not in database, no handle")
                    return True

            host_disk_info = FSRHostDisk.get_object_info_by_uuid(db, host_disk_object.uuid)
            if not strtobool(str(host_disk_info["state"])):
                # 如果已关磁盘清理，不处理
                logger.warning(f"ip:{ip} mountpoint:{mountpoint} is disable, no handle")
                return True

            if host_disk_info["status"] == "firing" and data["status"] == "firing":
                # 如果重复告警，不处理
                logger.warning(f"ip:{ip} mountpoint:{mountpoint} is firing, no handle")
                return True

            if data["status"] == "resolved":
                # 磁盘告警恢复，只更新告警状态
                host_disk_info["status"] = data["status"]
                FSRHostDisk.update(db, host_disk_info)
                logger.info(f"ip:{ip} mountpoint:{mountpoint} is resolved, no handle")
                return True

            # 处理服务器磁盘使用率过高
            result = self.task_host_disk_usage(db, data, host_disk_info)
            if not result:
                logger.error(f"handle host disk usage abnormal failed")
                return False

            logger.info(f"handle host disk usage abnormal success")
        except Exception as e:
            message = f"handle host disk usage abnormal error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True


    def task_host_disk_usage(self, db: Session, prom_data: dict, host_data: dict):
        """
        处理服务器磁盘使用率过高
        """
        headers = {
            "Content-Type": "application/json",
        }
        data = {
            "ip": host_data["ip"],
            "mountpoint": host_data['mountpoint'],
            "script": host_data['script']
        }

        try:
            # 回调磁盘清理接口
            req = requests.post(url=self.handle_url, headers=headers, data=json.dumps(data), timeout=5)
            if req.status_code != 200:
                message = f"故障自愈 => ip:{host_data['ip']} mountpoint:{host_data['mountpoint']} 回调磁盘清理失败"
                logger.error(message)
            else:
                message = f"故障自愈 => ip:{host_data['ip']} mountpoint:{host_data['mountpoint']} 回调磁盘清理成功"
                logger.info(message)
        except Exception as e:
            message = f"故障自愈 => ip:{host_data['ip']} mountpoint:{host_data['mountpoint']} 回调磁盘清理异常"
            logger.exception(f"{message} error: {e}")

        # 发送处理结果信息到企业微信群
        self.notice_tools.send_wechat_group(message)

        # 更新告警记录的comment信息
        update_info = {
            "uuid": prom_data["uuid"],
            "comment": message
        }
        result = PromAlarmRecord.update(db, update_info)
        if not result:
            logger.error(f"update alarm record to database failed")
            return False

        # 更新服务器磁盘清理告警状态
        host_data["status"] = prom_data["status"]
        result = FSRHostDisk.update(db, host_data)
        if not result:
            logger.error(f"update host disk to database failed")
            return False
        return True
